#!/usr/bin/python
from struct import pack
from struct import unpack
from struct import calcsize
from os.path import split
from os.path import sep
from os.path import splitext
from StructException import InvalidStringError

"""File Struct - Defines basic fields and methods pertinent to a file."""

class FileStruct:
	"""FileStruct defines a file: 
		location - path and filename of the original file,
		destination - path and filename of copy (or where copy is to be made),
		is_directory - whether file is a directory,
		host_id - computer hosting ftp server,
		state_id - file status; skip, pause, resume, replace,
		size - size of original file."""
	def __init__(T, file, dir, host, size):
		"""Initialize file: 
			file(location) - path and filename of file,
			dir(is_directory) - whether file is a directory,
			host(origin) - computer where the file originates from,
			size(location_size) - size of file."""		
		T.location = file
		if(file[len(file)-1]==sep)
			T.location = file[:-1]
		T.destination = None
		T.is_directory = 0
		if(dir):
			T.is_directory = 1
		T.host_id = host
		T.state_id = 0
		T.size = size
	def get_location(T):
		"""Returns location - the path and filename of original file."""
		return T.location
	def get_name(T):
		"""Returns file/dir name - the file/dir name with out the path."""
		return split(T.location)[1]
	def get_path(T):
		"""Returns the path - the path of file with out the filename."""
		return split(T.location)[0]
	def get_destination(T):
		"""Returns destination - the path and filename."""
		return T.destination
	def set_destination(T, file):
		"""Set destination to `file`(path and filename)."""
		T.destination = file
	def is_dir(T):
		"""Returns whether file is a directory."""
		return T.is_directory
	def get_host_id(T):
		"""Returns host(computer) where the file originates from."""
		return T.host_id
	def get_state_id(T):
		"""Return state(current status of file)."""
		return T.state
	def set_state_id(T, status):
		"""Set state to `status`(curent file status)."""
		T.state = status
	def get_size(T):
		"""Returns location_size(size of file)."""
		return T.size
#static variables
#ints: size,state_id,host_id,is_dir,location_size,destination_size
#strs: location,destination
int_fmt="l5i"
str_fmt="%is%is"
int_fmt_size=calcsize(int_fmt)
format=int_fmt+str_fmt

#static functions
def store(obj):
	"""Create a bit string coresponding to object."""
	if not obj:
		raise ValueError("NullPonterException: No FileStruct object found.")
	destination=obj.get_destination()
	if not destination:
		destination=""
	str_sizes=(len(obj.get_location()),len(destination))
	fmt=format%str_sizes
	return pack(fmt, obj.get_size(), obj.get_state_id(), obj.get_host_id(), obj.is_dir(), str_sizes[0], str_sizes[1], obj.get_location(), destination)
def create(bytes):
	"""Create an object from a bitstring."""
	if len(bytes)<int_fmt_size:
		raise InvalidStringError("Error creating UserStruct - int_fmt size does not match actual size. Format Size: %i"%int_fmt_size, bytes)
	#unpack ints
	(size,state_id,host_id,is_dir,location_size,destination_size) = unpack(int_fmt,bytes[:int_fmt_size]) 
	fmt_size=calcsize(format%(location_size,destination_size))
	if len(bytes)<fmt_size:
		raise InvalidStringError("UserStruct - Format size does not match actual size. Format Size: %i"%fmt_size, bytes)
	#unpack strs
	tmp_fmt=str_fmt % (location_size,destination_size)
	(location,destination) = unpack(tmp_fmt, bytes[int_fmt_size:])
	obj=FileStruct(location, is_dir, host_id, size)
	obj.set_destination(destination)
	obj.set_state_id(state_id)
	return obj

